#include "b_pawn.h"
#include "board.h"
#include <iostream>
#include "gameengine.h"

using namespace std;

Pawn::Pawn() {
}

Pawn::Pawn(int r, int c , Color color) {
	row = r;
	col = c;
	pColor = color;
	setImage();
}


Pawn::~Pawn() {

}

void Pawn::setImage() {
	if(pColor==white) {
		image = W_PAWN;
	} else {
		image = B_PAWN;
	}
}

void Pawn::GetAllPossible(std::vector <Cell>  & moves) {
	int rowCheck = 6;
	int inverse = 1;
	if(pColor == white) {
		inverse = -1;
	} else {
		rowCheck = 1;
	}
	if(row == rowCheck &&  !(myBoard->hasAnyPiece(row+1*inverse,col)) &&
	        !(myBoard->hasAnyPiece(row+2*inverse,col))) {
		moves.push_back(Cell(row+2*inverse,col));
	}
	if(MyFunctions::isInRange(row+1*inverse,col) &&
	        !(myBoard->hasAnyPiece(row+1*inverse,col))) {
		moves.push_back(Cell(row+1*inverse,col));
	}

	if(MyFunctions::isInRange(row+1*inverse,col+1*inverse) &&
	        myBoard->hasEnemy(pColor,row+1*inverse,col+1*inverse)) {
		moves.push_back(Cell(row+1*inverse,col+1*inverse));
	}

	if(MyFunctions::isInRange(row+1*inverse,col-1*inverse) &&
	        myBoard->hasEnemy(pColor,row+1*inverse,col-1*inverse)) {
		moves.push_back(Cell(row+1*inverse,col-1*inverse));
	}
	CheckEnPassant(moves , inverse);
}

void Pawn::CheckEnPassant(std::vector <Cell> & moves , int inverse) {

	if(myBoard->lastWasDoublePawn) {
		if(myBoard->lastDoublePawn.row == row) {
			if(myBoard->lastDoublePawn.col + 1 == col) {
				moves.push_back(Cell(row+1*inverse,col-1));
				myBoard->canDoEnPassant = true;
			}
			if(myBoard->lastDoublePawn.col - 1 == col) {
				moves.push_back(Cell(row+1*inverse,col+1));
				myBoard->canDoEnPassant = true;
			}
		}
	}
}

bool Pawn::isPiece() {
	return true;
}

void Pawn::setCell(int r, int c) {
	row = r;
	col = c;
}

Color Pawn::GetColor() {
	return pColor;
}

ImageName Pawn::GetImage() {
	return image;
}

bool Pawn::Test(std::ostream &os) {
	bool success = true;
	if (!Pawn::TestMoves(cout)) success = false;
	if (!Pawn::TestCheck(cout)) success = false;
	return success;
}

bool Pawn::TestCheck(ostream & os) {

	bool success = true;
	GameEngine testGame;
	testGame.gameStarted = true;
	testGame.turn = white;
	testGame.whiteIsComputer = false;
	testGame.blackIsComputer = false;
	testGame.myBoard.blackIsInCheck = false;
	testGame.myBoard.blackIsInCheckmate = false;
	testGame.myBoard.whiteIsInCheck = false;
	testGame.myBoard.whiteIsInCheckmate = false;

	/*
	0 1 2 3 4 5 6 7
	  0 . . . . . . . .
	  1 . . . . . . . .
	  2 . . . Q . . . .
	  3 Q . . . . . . .
	  4 . . . . Q . . .
	  5 . . p p . . . . TEST 1 | TEST 2
	  6 . . . k . . . .
	  7 . . . . . . . .
	*/
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(5,2,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(5,3,white));
	testGame.myBoard.piecesOnBoard.push_back(new King(6,3,white));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(3,0,black));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(2,3,black));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(4,4,black));
	testGame.myBoard.piecesOnBoard.push_back(new King(0,0,black));

	ChessPiece * p1 = testGame.myBoard.piecesOnBoard[0];
	ChessPiece * p2 = testGame.myBoard.piecesOnBoard[1];

	std::vector<ChessPiece *>::iterator it;
	for ( it = testGame.myBoard.piecesOnBoard.begin() ;
	        it < testGame.myBoard.piecesOnBoard.end() ; it++) {
		ChessPiece * p = *it;
		p->setBoard(&testGame.myBoard);
	}

	std::vector<Cell> moves1;
	std::vector<Cell> moves2;

	testGame.FindMoves(moves1,p1);
	testGame.FindMoves(moves2,p2);

	std::vector<Cell> answer1;
	std::vector<Cell> answer2;

	answer2.push_back(Cell(4,3));





	TEST(CheckCellVectors(moves1,answer1));
	TEST(CheckCellVectors(moves2,answer2));

	return success;
}

bool Pawn::TestMoves(std::ostream & os) {
	bool success = true;

	GameEngine testGame;
	testGame.gameStarted = true;
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(0,0,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(6,1,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(2,3,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(7,3,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(4,4,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(2,6,white));
	testGame.myBoard.piecesOnBoard.push_back(new Pawn(6,6,white));

	testGame.myBoard.piecesOnBoard.push_back(new Queen(6,2,white));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(6,3,white));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(6,4,white));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(3,4,white));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(1,5,black));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(5,6,black));
	testGame.myBoard.piecesOnBoard.push_back(new Queen(6,7,black));
	testGame.myBoard.piecesOnBoard.push_back(new King(3,0,black));
	testGame.myBoard.piecesOnBoard.push_back(new King(7,0,white));


	testGame.turn = white;
	ChessPiece * p1 = testGame.myBoard.piecesOnBoard[1-1];
	ChessPiece * p2 = testGame.myBoard.piecesOnBoard[2-1];
	ChessPiece * p3 = testGame.myBoard.piecesOnBoard[3-1];
	ChessPiece * p4 = testGame.myBoard.piecesOnBoard[4-1];
	ChessPiece * p5 = testGame.myBoard.piecesOnBoard[5-1];
	ChessPiece * p6 = testGame.myBoard.piecesOnBoard[6-1];
	ChessPiece * p7 = testGame.myBoard.piecesOnBoard[7-1];

	p1->setBoard(&testGame.myBoard);
	p2->setBoard(&testGame.myBoard);
	p3->setBoard(&testGame.myBoard);
	p4->setBoard(&testGame.myBoard);
	p5->setBoard(&testGame.myBoard);
	p6->setBoard(&testGame.myBoard);
	p7->setBoard(&testGame.myBoard);

	std::vector<Cell> moves1;
	std::vector<Cell> moves2;
	std::vector<Cell> moves3;
	std::vector<Cell> moves4;
	std::vector<Cell> moves5;
	std::vector<Cell> moves6;
	std::vector<Cell> moves7;

	p1->GetAllPossible(moves1);
	p2->GetAllPossible(moves2);
	p3->GetAllPossible(moves3);
	p4->GetAllPossible(moves4);
	p5->GetAllPossible(moves5);
	p6->GetAllPossible(moves6);
	p7->GetAllPossible(moves7);

	std::vector<Cell>answer1;
	std::vector<Cell>answer2;
	std::vector<Cell>answer3;
	std::vector<Cell>answer4;
	std::vector<Cell>answer5;
	std::vector<Cell>answer6;
	std::vector<Cell>answer7;

	answer2.push_back(Cell(5,1));
	answer2.push_back(Cell(4,1));

	answer3.push_back(Cell(1,3));

	answer6.push_back(Cell(1,6));
	answer6.push_back(Cell(1,5));

	answer7.push_back(Cell(5,7));


	TEST(CheckCellVectors(moves1,answer1));
	TEST(CheckCellVectors(moves2,answer2));
	TEST(CheckCellVectors(moves3,answer3));
	TEST(CheckCellVectors(moves4,answer4));
	TEST(CheckCellVectors(moves5,answer5));
	TEST(CheckCellVectors(moves6,answer6));
	TEST(CheckCellVectors(moves7,answer7));






	return success;
}

/*
  TEST MOVES------------------------

  Capital = black
  lower = white
  p = pawn
  Q = queen

    0 1 2 3 4 5 6 7
  0 p . . . . . . . TEST 1
  1 . . . . . Q . .
  2 . . . p . . p . TEST 3 | TEST 6
  3 . . . . q . . .
  4 . . . . p . . . TEST 5
  5 . . . . . . q Q
  6 . p q q q . p . TEST 2 | TEST 7
  7 . . . p . . . . TEST 4

  TEST CHECK------------------------

  Capital = black
  lower = white
  p = pawn
  q = queen
  k = king

    0 1 2 3 4 5 6 7
  0 . . . . . . . .
  1 . . . . . . . .
  2 . . . Q . . . .
  3 Q . . . . . . .
  4 . . . . Q . . .
  5 . . p p . . . . TEST 1 | TEST 2
  6 . . . k . . . .
  7 . . . . . . . .

    0 1 2 3 4 5 6 7
  0 . . . . . . . .
  1 . . . . . . . .
  2 . . . . . . . .
  3 . . . . . . . .
  4 . . . . . . . .
  5 . . . . . . . .
  6 . . . . . . . .
  7 . . . . . . . .


  */

bool Pawn::CheckCellVectors(std::vector<Cell> & first , std::vector <Cell> & second) {


	for ( int i = 0 ; i < first.size() ; i++ ) {
		Cell c = first[i];
		int row = c.row;
		int col = c.col;
		std::vector<Cell>::iterator it2;
		int pos = 0;
		bool passed = false;
		for ( it2=second.begin() ; it2 < second.end(); it2++ ) {
			Cell c2 = *it2;
			if(c2.row == row && c2.col == col) {
				second.erase(second.begin()+pos);
				passed = true;
			}
			pos++;
		}
		if(!passed) {

			return false;
		}
	}
	return true;
}

int Pawn::getValue()
{
    return 1;
}
